#coding:utf-8
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
import redis
import time
import json
import re
import sys

reload(sys)
sys.setdefaultencoding('utf8')
from config.tdm_config import *

city_index = {
    "北京": 1,
    "上海": 2,
    "天津": 3,
    "广州": 4,
    "苏州": 5,
}

def city_cmp(a, b):
    ret = city_index[a] - city_index[b]
    if ret == 0:
        return 0
    return ret > 0 and 1 or -1

def classroom_info_cmp(a, b):
    return a['name'] > b['name'] and 1 or -1

'''
------------------------------------------------------------------------------
[UTIL] user util functions
------------------------------------------------------------------------------
'''
def check_user_in_cookie(r, request, admin_role):
    user_name = ''
    user_role = False

    # no tdm_user in cookie
    if not "tdm_user" in request.COOKIES:
        print "tdm_user not in cookies"
        return False, user_name, user_role

    user_name = request.COOKIES.get("tdm_user", '')
    user_login_time = int(time.time() * 1000)
    user_key = '%s:%s' % (tdm_redis_key_user, user_name)
    user_info = r.get(user_key)
    print user_key, user_info

    # no user in database
    if user_info == None:
        print "%s user_info not found" % (user_name, )
        return False, user_name, user_role

    # key = tdm:user:qujianning
    # val = admin,1438310975786
    # ttl = 300
    user_info_last = user_info.split(',')
    user_role = user_info_last[0] == admin_role

    # check and update last login time
    login_alive_time = (user_login_time - int(user_info_last[1])) / (60 * 1000)
    if login_alive_time < 30:
        print "%s(%s) login success in %d min" % (user_name, request.META['REMOTE_ADDR'], login_alive_time)
        user_info_new = "%s,%s" % (user_info_last[0], user_login_time)
        r.set(user_key, user_info_new, ex=tdm_user_online_tm)
        return True, user_name, user_role

    # login overtime
    print "%s login overtime %s min" % (user_name, login_alive_time)
    return False, user_name, user_role


'''
------------------------------------------------------------------------------
[UTIL] city util functions
------------------------------------------------------------------------------
'''
def city_get_jxd_list(r, city):
    jxd_str = r.hget(tdm_redis_key_jxd, city)
    jxd_list = jxd_str and jxd_str.split(',') or []
    return jxd_list

def city_get_server_list(r, city):
    #北京_速八酒店教学点_10033-bj-tzjks-ics3: 172.16.71.201
    server_list = []
    server_key_list = r.hkeys(tdm_redis_key_server)
    server_key_list = [skl for skl in server_key_list if skl.find(city) == 0]
    for server_key in server_key_list:
        r_city, r_jxd, r_server = server_key.split(',')
        server_list.append(r_server)
    return server_list

def city_get_server_item_list(r, city):
    all_item_list = r.keys('%s:%s:*' % (tdm_redis_key_server_item_prefix, city))
    return list(all_item_list)

def city_get_warn_alert_nr(warn_alert):
    def _get_warn_alert_nr(fn):
        def __get_warn_alert_nr(r, module, city):
            nr = 0
            key = '%s:%s:%s:*' % (warn_alert, module, city)
            city_warn_alert_list = r.keys(key)
            return len(city_warn_alert_list)
        return __get_warn_alert_nr
    return _get_warn_alert_nr

@city_get_warn_alert_nr('warn')
def city_get_module_warn_nr(r, module, city):
    pass

@city_get_warn_alert_nr('alert')
def city_get_module_alert_nr(r, module, city):
    pass


'''
------------------------------------------------------------------------------
[UTIL] jxd util functions
------------------------------------------------------------------------------
'''
def jxd_get_server_list(r, city, jxd):
    #北京_速八酒店教学点_10033-bj-tzjks-ics3: 172.16.71.201
    server_list = []
    server_list_key = '%s:%s' % (city, jxd)
    server_key_list = r.hkeys(tdm_redis_key_server)
    server_key_list = [skl for skl in server_key_list if skl.find(server_list_key) == 0]
    for server_key in server_key_list:
        r_city, r_jxd, r_server = server_key.split(':')
        server_list.append(r_server)
    return server_list

def jxd_get_server_item_list(r, city, jxd):
    server_item_list = r.keys('%s:%s:%s:*' % (tdm_redis_key_server_item_prefix, city, jxd))
    return list(server_item_list)

def jxd_get_list_by_city(r, city):
    jxd_list = []
    for jxd in city_get_jxd_list(r, city):
        jxd_n = {}
        jxd_n['name'] = jxd
        jxd_list.append(jxd_n)
    return jxd_list


def venue_get_warn_alert_nr(warn_alert):
    def _get_warn_alert_nr(fn):
        def __get_warn_alert_nr(r, module, city, venue):
            nr = 0
            key = '%s:%s:%s:%s:*' % (warn_alert, module, city, venue)
            venue_warn_alert_list = r.keys(key)
            return len(venue_warn_alert_list)
        return __get_warn_alert_nr
    return _get_warn_alert_nr

@venue_get_warn_alert_nr('warn')
def venue_get_module_warn_nr(r, module, city, venue):
    pass

@venue_get_warn_alert_nr('alert')
def venue_get_module_alert_nr(r, module, city, venue):
    pass

def jxd_add(r, city, jxd):
    if not city in r.hkeys(tdm_redis_key_jxd):
        r.hset(tdm_redis_key_jxd, city, jxd)
    else:
        jxd_list = r.hget(tdm_redis_key_jxd, city).split(',')
        if not jxd in jxd_list:
            jxd_list.append(jxd)
            r.hset(tdm_redis_key_jxd, city, ','.join(jxd_list))

def jxd_del(r, city, jxd):
    jxd_str = r.hget(tdm_redis_key_jxd, city)
    if not jxd_str:
        return
    jxd_list = jxd_str.split(',')
    if jxd in jxd_list:
        new_jxd_list = [new_jxd for new_jxd in jxd_list if not new_jxd == jxd]
        r.hset(tdm_redis_key_jxd, city, ','.join(new_jxd_list))

def jxd_dis(r, city, jxd):
    if not city in r.hkeys(tdm_redis_key_jxd_dis):
        r.hset(tdm_redis_key_jxd_dis, city, jxd)
    else:
        jxd_list = r.hget(tdm_redis_key_jxd_dis, city).split(',')
        if not jxd in jxd_list:
            jxd_list.append(jxd)
            r.hset(tdm_redis_key_jxd_dis, city, ','.join(jxd_list))
        else:
            new_jxd_list = [new_jxd for new_jxd in jxd_list if not new_jxd == jxd]
            r.hset(tdm_redis_key_jxd_dis, city, ','.join(new_jxd_list))

def get_jxd_dis(r, city, jxd):
    jxd_dis_str = r.hget(tdm_redis_key_jxd_dis, city)
    if not jxd_dis_str:
        return False
    jxd_dis_list = jxd_dis_str.split(',')
    if jxd in jxd_dis_list:
        return True
    else:
        return False

'''
------------------------------------------------------------------------------
[UTIL] common util functions
------------------------------------------------------------------------------
'''
def tdm_dev_get_warn_alert_nr(hash_key):
    def _tdm_dev_get_warn_alert_nr(func):
        def __tdm_dev_get_warn_alert_nr(r, city, jxd, dev):
            nr = 0
            tdm_warn_alert_list = r.hkeys(hash_key)
            tdm_warn_alert_re = r'%s:%s:%s:.+' % (city, jxd, dev)
            for tdm_warn_alert in tdm_warn_alert_list:
                if re.match(tdm_warn_alert_re, tdm_warn_alert):
                    nr = nr + 1
            return nr
        return __tdm_dev_get_warn_alert_nr
    return _tdm_dev_get_warn_alert_nr

def tdm_item_get_warn_alert_nr(hash_key):
    def _tdm_item_get_warn_alert_nr(func):
        def __tdm_item_get_warn_alert_nr(r, city, jxd, dev, item):
            nr = 0
            tdm_warn_alert_list = r.hkeys(hash_key)
            tdm_warn_alert_re = r'%s:%s:%s:%s' % (city, jxd, dev, item)
            for tdm_warn_alert in tdm_warn_alert_list:
                if re.match(tdm_warn_alert_re, tdm_warn_alert):
                    nr = nr + 1
            return nr
        return __tdm_item_get_warn_alert_nr
    return _tdm_item_get_warn_alert_nr

'''
------------------------------------------------------------------------------
[UTIL] server util functions
------------------------------------------------------------------------------
'''

@tdm_dev_get_warn_alert_nr(tdm_redis_key_server_item_warn)
def server_get_warning_nr(r, city, jxd, server):
    pass

@tdm_dev_get_warn_alert_nr(tdm_redis_key_server_item_alert)
def server_get_alert_nr(r, city, jxd, server):
    pass

def server_get_item_list(r, city, jxd, server):
    #server_item_北京_和盛大厦_debian_cpuload
    db_items = r.keys('%s:%s:%s:%s:*' % (tdm_redis_key_server_item_prefix, city, jxd, server))
    re_server_item = r'%s:([^:]+):([^:]+):([^:]+):(.*)' % (tdm_redis_key_server_item_prefix,)
    item_list = []
    for rs_i in db_items:
        rs_g = re.match(re_server_item, rs_i).groups()
        if len(rs_g) == 4:
            item_list.append(rs_g[3])
    return item_list

def server_add(r, city, jxd, server, ipaddr):
    server_list_key = '%s:%s:%s' % (city, jxd, server)
    server_attr = {}
    server_attr['ipaddr'] = ipaddr
    r.hset(tdm_redis_key_server, server_list_key, json.dumps(server_attr))

def server_del(r, city, jxd, server):
    server_list_key = '%s:%s:%s' % (city, jxd, server)
    r.hdel(tdm_redis_key_server, server_list_key)

def server_get_item_status(r, city, jxd, server, item):
    #server_item_北京_和盛大厦_debian_online:1421895226983:-1
    server_item_name = '%s:%s:%s:%s:%s' % (tdm_redis_key_server_item_prefix, city, jxd, server, item)
    server_item_key_list = r.hkeys(server_item_name)
    if server_item_key_list:
        server_item_key_list.sort()
        return r.hget(server_item_name, server_item_key_list[-1])
    else:
        return ''

def server_get_info(r, city, jxd, server):
    #config_server: 北京_城乡华懋_10026-bj-gzfcx-ics3: {"ipaddr": "172.16.43.201"}
    server_attr_key = '%s:%s:%s' % (city, jxd, server)
    server_attr_str = r.hget(tdm_redis_key_server, server_attr_key)
    server_attr = json.loads(server_attr_str)
    server_info = {}
    server_info['city'] = city
    server_info['jxd'] = jxd
    server_info['name'] = server
    server_info['warning_nr'] = server_get_warning_nr(r, city, jxd, server)
    server_info['alert_nr'] = server_get_alert_nr(r, city, jxd, server)
    server_info['ipaddr'] = server_attr.get('ipaddr', '')
    server_info['online'] = server_get_item_status(r, city, jxd, server, tdm_redis_key_server_online_suffix)
    server_info['cpuload'] = server_get_item_status(r, city, jxd, server, 'cpuload')
    server_info['memload'] = server_get_item_status(r, city, jxd, server, 'memload')
    server_info['procnr'] = server_get_item_status(r, city, jxd, server, 'procnr')

    #print server_info
    return server_info

def server_get_info_list(r, city, jxd):
    server_info_list = []
    server_list = jxd_get_server_list(r, city, jxd)
    for server in server_list:
        server_info_list.append(server_get_info(r, city, jxd, server))
    return server_info_list

def server_get_warn_alert_list_by_keys(r, item_name_list):
    server_name_list = []
    server_list = []
    re_server_item = r'item_([^:]+):([^:]+):([^:]+):([^:]+):(.*)'
    for rs_i in item_name_list:
        rs_g = re.match(re_server_item, rs_i).groups()
        if len(rs_g) == 5 and not rs_g[3] in server_name_list:
            server_name_list.append(rs_g[3])
            server_list.append(server_get_info(r, rs_g[0], rs_g[1], rs_g[3]))
    return server_list


'''
------------------------------------------------------------------------------
[UTIL] network util functions
------------------------------------------------------------------------------
'''
def network_dev_list(r, city, jxd):
    netdev_list = []
    netdev_name_re = '%s:%s:(.*)' % (city, jxd)
    netdev_name_list = r.hkeys(tdm_redis_key_network)
    for netdev in netdev_name_list:
        netdev_match = re.match(netdev_name_re, netdev)
        if netdev_match:
            netdev_name = netdev_match.groups()[0]
            netdev_list.append(netdev_name)
    return netdev_list

@tdm_dev_get_warn_alert_nr(tdm_redis_key_network_item_warn)
def network_get_warning_nr(r, city, jxd, netdev):
    pass

@tdm_dev_get_warn_alert_nr(tdm_redis_key_network_item_alert)
def network_get_alert_nr(r, city, jxd, netdev):
    pass

@tdm_item_get_warn_alert_nr(tdm_redis_key_network_item_warn)
def network_item_get_warning_nr(r, city, jxd, dev, item):
    pass

@tdm_item_get_warn_alert_nr(tdm_redis_key_network_item_alert)
def network_item_get_alert_nr(r, city, jxd, dev, item):
    pass


def network_get_item(r, city, jxd, netdev, item, last_time):
    #network_item_北京_中鼎大厦B座_路由_online
    item_name = '%s:%s:%s:%s:%s' % (tdm_redis_key_network_item_prefix, city, jxd, netdev, item)
    item_key_list = r.hkeys(item_name)

    if len(item_key_list) == 0:
        return []

    item_key_list.sort(reverse=True)

    if last_time == -1:
        return r.hget(item_name, item_key_list[0])

    json_dict = {
        'name'  : item,
        'data'  : []
    }
    for item_key_time in item_key_list:
        if int(item_key_time) > last_time:    #item_key_time >= start and item_key_time <= end:
            json_dict['data'].append([int(item_key_time), int(r.hget(db_item, item_key_time))])

    ret = [json_dict]
    return ret

def netdev_add(r, city, jxd, new_netdev, new_ipaddr):
    network_dev_key = '%s:%s:%s' % (city, jxd, new_netdev)
    network_dev_val = new_ipaddr
    r.hset(tdm_redis_key_network, network_dev_key, network_dev_val)

def netdev_del(r, city, jxd, netdev):
    network_dev_key = '%s:%s:%s' % (city, jxd, netdev)
    r.hdel(tdm_redis_key_network, network_dev_key)

def netdev_get_info(r, city, jxd, netdev):
    netdev_attr = r.hget(tdm_redis_key_network, '%s:%s:%s' % (city, jxd, netdev))
    netdev_attr_dict = json.loads(netdev_attr)
    network_info = {}
    network_info['city'] = city
    network_info['jxd'] = jxd
    network_info['name'] = netdev
    network_info['ipaddr'] = netdev_attr_dict.get('ipaddr')
    network_info['online'] = network_get_item(r, city, jxd, netdev, 'online', -1)
    network_info['portnr'] = 0
    network_info['portflow'] = 0
    network_info['warning_nr'] = network_get_warning_nr(r, city, jxd, netdev)
    network_info['alert_nr'] = network_get_alert_nr(r, city, jxd, netdev)
    return network_info

def network_get_list_info(r, city, jxd):
    netdev_list = []
    for netdev in network_dev_list(r, city, jxd):
        netdev_list.append(netdev_get_info(r, city, jxd, netdev))
    return netdev_list


'''
------------------------------------------------------------------------------
[UTIL] mdm util functions
------------------------------------------------------------------------------
'''
def mdm_classroom_list(r, city, jxd):
    classroom_list = []
    classroom_name_re = '%s:%s:(.*)' % (city, jxd)
    classroom_name_list = r.hkeys(tdm_redis_key_mdm)
    for classroom in classroom_name_list:
        classroom_match = re.match(classroom_name_re, classroom)
        if classroom_match:
            classroom_name = classroom_match.groups()[0]
            classroom_list.append(classroom_name)
    return classroom_list

def mdm_dev_list_get(r, city, jxd, classroom):
    mdm_dev_list = []
    classroom_key = '%s:%s:%s' % (city, jxd, classroom)
    classroom_macaddr_str = r.hget(tdm_redis_key_mdm, classroom_key)
    if classroom_macaddr_str:
        mdm_dev_list = classroom_macaddr_str.split(',')
    return mdm_dev_list

def classroom_get_info(r, city, jxd, classroom):
    #name = config_mdm
    #key = 北京_和盛大厦_605
    #value = 00-11-23-33-44-55,00-11-23-33-44-56
    classroom_macaddr_list = mdm_dev_list_get(r, city, jxd, classroom)

    #name = mdm_item:北京:和盛大厦:605:00-11-23-33-44-55
    #key = 1421111666928
    #value = {"alive": 1}
    macaddr_online_list = []
    cur_time = int(time.time())
    for macaddr in classroom_macaddr_list:
        macaddr_online_name = '%s:%s:%s:%s:%s' % (tdm_redis_key_mdm_item_prefix, city, jxd, classroom, macaddr)
        macaddr_online_key = r.hkeys(macaddr_online_name)
        macaddr_online_key.sort(reverse=True)
        #print macaddr_online_name
        #print cur_time
        #print macaddr_online_key
        if len(macaddr_online_key) > 0 and cur_time - int(macaddr_online_key[0])/1000 < 3600 * 2:
            macaddr_online_list.append(macaddr)

    classroom_info = {}
    classroom_info['city'] = city
    classroom_info['jxd'] = jxd
    classroom_info['name'] = classroom
    classroom_info['mac_list'] = classroom_macaddr_list
    classroom_info['online_list'] = macaddr_online_list
    return classroom_info

def classroom_get_list_info(r, city, jxd):
    classroom_list = []
    for classroom in mdm_classroom_list(r, city, jxd):
        classroom_list.append(classroom_get_info(r, city, jxd, classroom))
    classroom_list.sort(classroom_info_cmp)
    return classroom_list

def mdm_get_info(r, city, jxd, classroom, macaddr):
    mdm_info = {}
    macaddr_online_name = '%s:%s:%s:%s:%s' % (tdm_redis_key_mdm_item_prefix, city, jxd, classroom, macaddr)
    macaddr_online_key = r.hkeys(macaddr_online_name)
    macaddr_online_key.sort(reverse=True)
    #print macaddr, macaddr_online_name, macaddr_online_key
    if len(macaddr_online_key) > 0:
        mdm_info_content = json.loads(r.hget(macaddr_online_name, macaddr_online_key[0]))
        ipaddr = mdm_info_content.get('ipaddr', '0.0.0.0')
        battery = mdm_info_content.get('battery', '0')
        uptime = mdm_info_content.get('uptime', '0')
        memory = mdm_info_content.get('memory', '0')
        storage = mdm_info_content.get('storage', '0')
        wifistrength = mdm_info_content.get('wifistrength', '0')
        fmver = mdm_info_content.get('fmver', '0')
        devtype = mdm_info_content.get('devtype', '0')
        #battery = mdm_info_content.get('battery', '0')
        mdm_info['city'] = city
        mdm_info['jxd'] = jxd
        mdm_info['classroom'] = classroom
        mdm_info['macaddr'] = macaddr.upper()
        mdm_info['ipaddr'] = ipaddr
        mdm_info['lasttime'] = macaddr_online_key[0]
        mdm_info['battery'] = battery and int(battery) or 0
        mdm_info['uptime'] = uptime and int(uptime) or 0
        #mdm_info['softlist'] = 0
        #mdm_info['activesoft'] = 0
        mdm_info['memory'] = memory
        mdm_info['storage'] = storage
        mdm_info['wifistrength'] = wifistrength
        #mdm_info['osversion'] = 0
        mdm_info['fmver'] = fmver
        mdm_info['devtype'] = devtype

    #print mdm_info
    return mdm_info

def mdm_get_list_info(r, city, jxd, classroom):
    mdm_info_list = []
    for mdm_dev in mdm_dev_list_get(r, city, jxd, classroom):
        mdm_info = mdm_get_info(r, city, jxd, classroom, mdm_dev)
        if mdm_info:
            mdm_info_list.append(mdm_info)
    return mdm_info_list

'''
------------------------------------------------------------------------------
[UTIL] acard util functions
------------------------------------------------------------------------------
'''
def acard_get_data_core(r, city):
    attend_data_key = '%s:%s:%s' % (tdm_data_key_attend, tdm_data_attend_core, city)
    attend_data_val = r.get(attend_data_key)
    return attend_data_val

def acard_get_data_yewu(r, city):
    attend_data_key = '%s:%s:%s' % (tdm_data_key_attend, tdm_data_attend_yewu, city)
    attend_data_val = r.get(attend_data_key)
    return attend_data_val

def acard_get_cardreader_by_city(r, city):
    '''{
        "crstatus":
            [
            {"status": true, "ip": "192.168.2.101"},
            {"status": true, "ip": "192.168.2.102"},
            {"status": true, "ip": "192.168.2.103"},
            {"status": true, "ip": "192.168.2.104"}
            ],
        }
    '''
    cardreader_num = 0
    venue_data_name = '%s:%s:*' % (redis_venue_sync_log_prefix, city)
    for ctm_key in r.keys(venue_data_name):
        ctm_data = json.loads(r.get(ctm_key))
        if ctm_data.get('ip_100', False):
            cardreader_num += len(ctm_data.get("crstatus", []))
    return cardreader_num
